package cn.tuling.v3;

import java.util.ArrayList;
import java.util.List;

/**
 *  增加观察者、被观察者接口
 *  好处：
 *  1. 符合“开闭原则”，实现类解耦，抽象耦合。想要新增观察者，实现观察者接口，修改客户端类即可。
 */
public class ObserverTest {
    public static void main(String[] args) {
        HanFeiZi hanFeiZi = new HanFeiZi();
        hanFeiZi.addObserver(new LiSi());
        hanFeiZi.addObserver(new WangWu());
        hanFeiZi.haveBreakfast();
        hanFeiZi.haveFun();
    }
}

interface Observer {
    void update(String context);
}

class LiSi implements Observer {

    @Override
    public void update(String context) {
        System.out.println("李斯：观察到了韩非子新活动。");
        this.reportToQinShiHuang(context);
        System.out.println("李斯：报告完毕。");
    }

    private void reportToQinShiHuang(String context) {
        System.out.println("李斯：报告秦老板，giao~");
    }
}

class WangWu implements Observer {

    @Override
    public void update(String context) {
        System.out.println("王五：观察到了韩非子新活动。");
        this.reportToZhaoLiu(context);
        System.out.println("王五：报告完毕。");
    }

    private void reportToZhaoLiu(String context) {
        System.out.println("王五：报告赵老大，芜湖~");
    }
}

interface Observable {
    void addObserver(Observer observer);

    void removeObserver(Observer observer);

    void notifyObservers(String context);
}

interface IHanFeiZi {
    void haveBreakfast();
    void haveFun();
}

class HanFeiZi implements Observable, IHanFeiZi {
    private List<Observer> observers = new ArrayList<>();

    @Override
    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers(String context) {
        for (Observer observer : observers) {
            observer.update(context);
        }
    }

    @Override
    public void haveBreakfast() {
        System.out.println("韩非子：吃饭饭");
        notifyObservers("吃饭饭");
    }

    @Override
    public void haveFun() {
        System.out.println("韩非子：打豆豆");
        notifyObservers("打豆豆");
    }
}
